#pragma once
#include "..\Math\Vec2i.h"
#include <libtcod\libtcod.hpp>
#include <memory>
#include <functional>
#include <vector>

typedef std::shared_ptr<TCODConsole> TCODConsolePtr;

class InputManager;
typedef std::shared_ptr<InputManager> InputManagerPtr;

class Player;
typedef std::shared_ptr<Player> PlayerPtr;

class TerrainTypeManager;
typedef std::shared_ptr<TerrainTypeManager> TerrainTypeManagerPtr;
/*class Forest;
typedef std::shared_ptr<Forest> ForestPtr;
class Weather;
typedef std::shared_ptr<Weather> WeatherPtr;

class World;
typedef std::shared_ptr<World> WorldPtr;*/

namespace World
{
	class TheWorld;
	typedef std::shared_ptr<TheWorld> WorldPtr;
}

class DeferredRenderer;
typedef std::shared_ptr<DeferredRenderer> DeferredRendererPtr;

class GameManager;
typedef std::shared_ptr<GameManager> GameManagerPtr;

class GameManager
{
public:
	static GameManagerPtr getSingleton();
	GameManager();
	~GameManager();

	void init(int argc, char **argv);
	void run();

	const Vec2i &getMapViewport() const { return map_viewport; }
	const Vec2i &getStoryViewport() const { return story_viewport; }

	const TCODConsolePtr &getMapConsole() const { return map_console; }
	const TCODConsolePtr &getStoryConsole() const { return story_console; }

	const InputManagerPtr &getInputMgr() const { return input_mgr; }
	
	const PlayerPtr &getPlayer() const { return player; }

	const TerrainTypeManagerPtr &getTerrainTypeMgr() const { return terrain_type_mgr; }
	/*const ForestPtr &getForest() const { return forest; }
	const WeatherPtr &getWeather() const { return weather; }*/

	//const WorldPtr &getWorld() const { return world; }

	const DeferredRendererPtr &getRenderer() const { return renderer; }

	void quit() { quit_ = true; }

private:
	static GameManagerPtr singleton;

	Vec2i map_viewport;
	Vec2i story_viewport;
	TCODConsolePtr map_console;
	TCODConsolePtr story_console;

	InputManagerPtr input_mgr;
	PlayerPtr player;
	TerrainTypeManagerPtr terrain_type_mgr;
	/*ForestPtr forest;
	WeatherPtr weather;*/

	//WorldPtr world;
	World::WorldPtr world;

	DeferredRendererPtr renderer;

	bool quit_;
};
